using System.Linq;
using ilgolosone.DomainModel.Entities;
using ilgolosone.DomainModel.Queries;
using ilgolosone.DomainModel.Repositories;
using ilgolosone.Persistence.NH.Data.Impl;
using ilgolosone.Persistence.NH.Repositories;
using NUnit.Framework;

namespace ilgolosone.Persistence.NH.UnitTests
{
    [TestFixture]
    public class SpecialtyFixture : PersistenceFixtureBase
    {
        [Test]
        public void esistono_dei_dati_sulle_specialita()
        {
            ConsumeUOW(uow =>
               {
                   var repository = new NHibernateRepository<Specialty>(uow);
                   repository.Any().Should().Be.True();
               });
        }

        [Test]
        public void ricerca_di_una_specialita_esistente()
        {
            const string SPECIALTY_TO_FIND = "Specialita01";
            
            ConsumeUOW(uow =>
               {
                   var repository = new NHibernateRepository<Specialty>(uow);
                   FindSpecialtyByName query = new FindSpecialtyByName(SPECIALTY_TO_FIND);
                   var result = repository.Filter(query).Single();
                   result.Should().Not.Be.Null();
                   result.Name.Should().Equals(SPECIALTY_TO_FIND);
               });
        }

        [Test]
        public void ricerca_di_un_insieme_di_specialita()
        {
            const int TEST_SPECIALTY_COUNT = 5;

            ConsumeUOW(uow =>
               {
                   var repository = new NHibernateRepository<Specialty>(uow);
                   FindSpecialtyByPartOfName query = new FindSpecialtyByPartOfName("Spec");
                   var result = repository.Filter(query).ToList();
                   result.Should().Not.Be.Null();
                   result.Count().Should().Be.Equals(TEST_SPECIALTY_COUNT);
               });
        }

        [Test]
        public void ricerca_di_una_specialita_inesistente()
        {
            const string UNKNOWN_SPECIALTY_TO_FIND = "xxx";

            ConsumeUOW(uow =>
                {
                    var repository = new NHibernateRepository<Specialty>(uow);
                    FindSpecialtyByName query = new FindSpecialtyByName(UNKNOWN_SPECIALTY_TO_FIND);
                    var result = repository.Filter(query).FirstOrDefault();
                    result.Should().Be.Null();
                });
        }

        [Test]
        public void modifica_di_una_specialita()
        {
            const string SPECIALTY_TO_EDIT = "Specialita01";
            const string NEW_DESCRIPTION = "Descrizione modificata";

            FindSpecialtyByName query = new FindSpecialtyByName(SPECIALTY_TO_EDIT);

            ConsumeUOW(uow =>
                {
                    var repository = new NHibernateRepository<Specialty>(uow);
                    var result = repository.Filter(query).Single();
                    result.Description = NEW_DESCRIPTION;
                    uow.Commit();
                });

            ConsumeUOW(uow =>
                {
                    var repository = new SpecialtyRepository(uow);
                    var result = repository.Filter(query).Single();
                    result.Description.Should().Be.EqualTo(NEW_DESCRIPTION);
                    repository.StoredProc().Should().Not.Be.Empty();
                });
        }

        [Test]
        public void cancellazione_di_una_specialita()
        {
            const string SPECIALTY_TO_DELETE = "Specialita00";

            ConsumeUOW(uow =>
                {
                    var repository = new NHibernateRepository<Specialty>(uow);
                    var result = repository.Filter(new FindSpecialtyByName(SPECIALTY_TO_DELETE)).Single();
                    repository.Delete(result);
                    uow.Commit();
                });

            ConsumeUOW(uow =>
                {
                    var repository = new NHibernateRepository<Specialty>(uow);
                    repository.Filter(new FindSpecialtyByName(SPECIALTY_TO_DELETE)).ToArray().Should().Be.Empty();
                });
        }
    }
}